package yyy.ab.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import yyy.ab.common.core.BaseServiceImpl;
import yyy.ab.common.core.Query;
import yyy.ab.common.core.ResultBean;
import yyy.ab.common.exception.EntityExistException;
import yyy.ab.common.utils.StringUtils;
import yyy.ab.common.utils.ValidationUtil;
import yyy.ab.modules.system.entity.SysUser;
import yyy.ab.modules.system.entity.SysUserRole;
import yyy.ab.modules.system.entity.dto.SysRoleSmallDto;
import yyy.ab.modules.system.mapper.SysUserMapper;
import yyy.ab.modules.system.mapper.SysUserRoleMapper;
import yyy.ab.modules.system.service.SysUserService;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@Transactional
@RequiredArgsConstructor
public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    private final PasswordEncoder passwordEncoder;
    private final SysUserRoleMapper userRoleMapper;

    @Override
    public SysUser findByUsername(String username) {
        SysUser sysUser = baseMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getUsername, username));
        return sysUser;
    }

    @Override
    public IPage<SysUser> findPage(Map<String, Object> params) {
        Object keyword = params.get("keyword");
        Object organizationIds = params.get("organizationIds");

        Page<SysUser> page = new Query<SysUser>(params).getPage();
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isNullOrEmpty(organizationIds)) {
            queryWrapper.in("organization_id", organizationIds.toString().split(","));
        }
        if (!StringUtils.isNullOrEmpty(keyword)) {
            queryWrapper.and(o -> o.like("username", keyword).or().like("nick_name", keyword));
        }

        Page<SysUser> sysUserPage = baseMapper.selectPage(page, queryWrapper);
        if (sysUserPage.getRecords() != null && sysUserPage.getRecords().size() > 0) {
            for (SysUser sysUser : sysUserPage.getRecords()) {
                sysUser.setRoleList(userRoleMapper.findRoleSmallByUserId(sysUser.getId()));
            }
        }
        return sysUserPage;
    }

    @Override
    @Transactional
    public ResultBean create(SysUser entity) {
        Map<String, Object> colMap = new HashMap<>();
        colMap.put("username", entity.getUsername());
        List<SysUser> sysUsers = baseMapper.selectByMap(colMap);
        if (sysUsers != null && sysUsers.size() > 0) {
            throw new EntityExistException(SysUser.class, "username", entity.getUsername());
        }
        String password = passwordEncoder.encode("123456");
        entity.setPassword(password);
        entity.setEnabled(1);
        ResultBean resultBean = super.create(entity);
        if (resultBean.getSuccess() && entity.getRoleList() != null && entity.getRoleList().size() > 0) {
            for (SysRoleSmallDto smallDto : entity.getRoleList()) {
                SysUserRole userRole = new SysUserRole();
                userRole.setUserId(entity.getId());
                userRole.setRoleId(smallDto.getValue());
                userRoleMapper.insert(userRole);
            }
        }
        return resultBean;
    }

    @Override
    @Transactional
    public ResultBean update(SysUser entity) {
        SysUser sysUser = baseMapper.selectById(entity.getId());
        ValidationUtil.isNull(sysUser, "User", "id", entity.getId());
        sysUser.setUsername(entity.getUsername());
        sysUser.setNickName(entity.getNickName());
        sysUser.setEmail(entity.getEmail());
        sysUser.setOrganizationId(entity.getOrganizationId());
        sysUser.setGender(entity.getGender());
        sysUser.setPhone(entity.getPhone());
        ResultBean resultBean = super.update(entity);
        if (resultBean.getSuccess()) {
            Map<String, Object> deleteMap = new HashMap<>();
            deleteMap.put("user_id", entity.getId());
            userRoleMapper.deleteByMap(deleteMap);
            if (entity.getRoleList() != null && entity.getRoleList().size() > 0) {
                for (SysRoleSmallDto smallDto : entity.getRoleList()) {
                    SysUserRole userRole = new SysUserRole();
                    userRole.setUserId(entity.getId());
                    userRole.setRoleId(smallDto.getValue());
                    userRoleMapper.insert(userRole);
                }
            }
        }
        return resultBean;
    }

    @Override
    public ResultBean updateStatus(Long userId, Integer enabled) {
        SysUser sysUser = baseMapper.selectById(userId);
        ValidationUtil.isNull(sysUser, "User", "id", userId);
        sysUser.setEnabled(enabled);
        ResultBean resultBean = super.update(sysUser);
        return resultBean;
    }

    @Override
    public ResultBean resetPassword(Long userId) {
        SysUser sysUser = baseMapper.selectById(userId);
        ValidationUtil.isNull(sysUser, "User", "id", userId);
        sysUser.setPassword(passwordEncoder.encode("123456"));
        ResultBean resultBean = super.update(sysUser);
        return resultBean;
    }
}
